import json

from channels.generic.websocket import AsyncJsonWebsocketConsumer
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync


class RollCallConsumer(AsyncJsonWebsocketConsumer):
    group_name = "default_group"

    async def connect(self):
        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.group_name,
            self.channel_name
        )

    async def receive(self, text_data=None, bytes_data=None, **kwargs):
        await self.send(text_data)

    async def send(self, text_data=None, bytes_data=None, close=False):
        await super(RollCallConsumer, self).send(text_data, bytes_data, close)

    async def push_messages(self, message):
        message_type = message['default_group']
        message = message['message']
        data = {
            'message_type': message_type,
            'message': message
        }
        await self.send(json.dumps(data, ensure_ascii=False))


class CustomRollCallConsumer(AsyncJsonWebsocketConsumer):
    group_name = "default_group"

    async def connect(self):
        self.group_name = self.scope['url_route']['kwargs'].get('group', 'default_group')
        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        self.group_name = self.scope['url_route']['kwargs'].get('group', 'default_group')
        await self.channel_layer.group_discard(
            self.group_name,
            self.channel_name
        )

    async def receive(self, text_data=None, bytes_data=None, **kwargs):
        await self.send(text_data)

    async def send(self, text_data=None, bytes_data=None, close=False):
        await super(CustomRollCallConsumer, self).send(text_data, bytes_data, close)

    async def push_messages(self, message):
        message_type = message['default_group']
        message = message['message']
        data = {
            'message_type': message_type,
            'message': message
        }
        await self.send(json.dumps(data, ensure_ascii=False))


def send_message(group_name="default_group", message=None, message_type=None):
    """
    WS广播: 外部函数调用
    :param message_type: 消息类型
    :param group_name: 组名称
    :param message: 消息内容
    :return:
    """
    # print(get_channel_layer())
    # print("send msg")
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        group_name,
        {
            'type': 'push.messages',  # push_messages函数
            'message': message,
            'message_type': message_type
        }
    )
